#include "myfilewg.h"
#include "ui_myfilewg.h"

#include <QFileDialog>
#include <QHttpMultiPart>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonParseError>
#include <QMenu>
#include <QMessageBox>
#include <QMimeDatabase>
#include <QNetworkReply>
#include <common/downloadtask.h>
#include <common/logininfoinstance.h>
#include <common/uploadtask.h>
#include <widget/filepropertyinfo.h>

myfilewg::myfilewg(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::myfilewg)
{
    ui->setupUi(this);

    //初始化
    initListWidget();

    //右键添加菜单
    addActionMenu();

    m_manager = Common::getNetManager();

    //定时检查任务队列
    checkTaskList();
}

myfilewg::~myfilewg()
{
    delete ui;
}

void myfilewg::initListWidget()
{
    ui->listWidget->setViewMode(QListView::IconMode);;
    ui->listWidget->setIconSize(QSize(40, 40));
    ui->listWidget->setGridSize(QSize(60, 100));

    ui->listWidget->setResizeMode(QListView::Adjust);

    ui->listWidget->setMovement(QListView::Static);
    //设置图标之间的间距，当setGridSize（）时，此选项无效
    ui->listWidget->setSpacing(30);

    ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->listWidget, &QListWidget::customContextMenuRequested, this, &myfilewg::rightMenu);

    connect(ui->listWidget, &QListWidget::itemPressed, this, [=](QListWidgetItem* item)
    {
        QString str = item->text();
        if(str == "上传文件")
        {
            addUploadFiles();
        }
    });
}

void myfilewg::addActionMenu()
{
    m_menu = new QMenu(this);

    m_downloadAction = new QAction("下载", this);
    m_shareAction = new QAction("分享", this);
    m_delAction = new QAction("删除", this);
    m_propertyAction = new QAction("属性", this);

    m_menu->addAction(m_downloadAction);
    m_menu->addAction(m_shareAction);
    m_menu->addAction(m_delAction);
    m_menu->addAction(m_propertyAction);

    m_menuEmpty = new QMenu(this);

    m_pvAscendingAction = new QAction("按下载量升序", this);
    m_pvDescendingAction = new QAction("按下载量降序", this);
    m_refreshAction = new QAction("刷新", this);
    m_uploadAction = new QAction("上传", this);

    m_menuEmpty->addAction(m_pvAscendingAction);
    m_menuEmpty->addAction(m_pvDescendingAction);
    m_menuEmpty->addAction(m_refreshAction);
    m_menuEmpty->addAction(m_uploadAction);

    connect(m_downloadAction, &QAction::triggered, [=]()
    {
        cout << "下载动作";
        addDownloadFiles();
    });

    connect(m_shareAction, &QAction::triggered, [=]()
    {
        cout << "分享动作";
        dealSelectdFile("分享");
    });

    connect(m_delAction, &QAction::triggered, [=]()
    {
        cout << "删除动作";
        dealSelectdFile("删除");
    });

    connect(m_propertyAction, &QAction::triggered, [=]()
    {
        cout << "属性动作";
        dealSelectdFile("属性");
    });

    connect(m_pvAscendingAction, &QAction::triggered, [=]()
    {
        cout << "按下载量升序";
        refreshFiles(PvAsc);
    });

    connect(m_pvDescendingAction, &QAction::triggered, [=]()
    {
        cout << "按下载量降序";
        refreshFiles(PvDesc);
    });

    connect(m_refreshAction, &QAction::triggered, [=]()
    {
        cout << "刷新动作";
        refreshFiles();
    });

    connect(m_uploadAction, &QAction::triggered, [=]()
    {
        cout << "上传动作";
        addUploadFiles();
    });
}

void myfilewg::checkTaskList()
{
    connect(&m_uploadFileTimer, &QTimer::timeout, [=]()
    {
        uploadFilesAction();
    });

    m_uploadFileTimer.start(500);

    connect(&m_downloadTimer, &QTimer::timeout,[=]()
    {
        downloadFilesAction();
    });

    m_downloadTimer.start(500);
}

void myfilewg::addUploadFiles()
{
    emit gotoTransfer(TransferStatus::Upload);
    UploadTask* uploadList = UploadTask::getInstance();
    if(uploadList == NULL)
    {
        cout << "UploadTask::getInstance() == NULL";
        return;
    }

    QStringList list = QFileDialog::getOpenFileNames();
    for(int i = 0; i < list.size(); ++i)
    {
        int res = uploadList->appendUploadList(list.at(i));
        if(res == -1)
        {
            QMessageBox::warning(this, "文件太大", "文件大小太大");
        }
        else if(res == -2)
        {
            QMessageBox::warning(this, "添加失败", "上传的文件是否已经在上传队列中！！");
        }
        else if(res == -3)
        {
            cout << "打开文件失败";
        }
        else if(res == -4)
        {
            cout << "获取布局失败";
        }
    }
}

void myfilewg::refreshFiles(Display cmd)
{
    m_userFilesCount = 0;

    QNetworkRequest request;

    LoginInfoInstance* login =  LoginInfoInstance::getInstance();

    QString url = QString("http://%1:%2/myfiles?cmd=count").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QByteArray data = setGetCountJson(login->getUser(), login->getToken());

    cout << data << endl;

    QNetworkReply* reply = m_manager->post(request, data);
    if(reply == nullptr)
    {
        cout << "reply == nullptr";
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            refreshFileItems();
            return;
        }

        QByteArray array = reply->readAll();
        reply->deleteLater();

        cout << "array: " << array;

        QStringList list = getCountStatus(array);
        if(list.at(0) == "111")
        {
            QMessageBox::warning(this, "账号异常", "请重新登录");
            emit loginAgainSignal();
            return;
        }

        m_userFilesCount = list.at(1).toLong();
        cout << "userFilesCount = " << m_userFilesCount;

        clearFileList();

        if(m_userFilesCount > 0)
        {
            m_start = 0;
            m_count = 10;

            getUserFilesList(cmd);
        }
        else
        {
            refreshFileItems();
        }
    });
}

void myfilewg::clearAllTask()
{
    UploadTask* uploadList = UploadTask::getInstance();
    if(uploadList == nullptr)
    {
        cout << "UploadTask::getInstance() error";
        return;
    }

    uploadList->clearList();
}

void myfilewg::rightMenu(const QPoint &pos)
{
    QListWidgetItem* item = ui->listWidget->itemAt(pos);
    if(item == nullptr)
    {
        m_menuEmpty->exec(QCursor::pos());
    }
    else
    {
        ui->listWidget->setCurrentItem(item);

        if(item->text() == "上传文件")
        {
            return;
        }

        m_menu->exec(QCursor::pos());
    }
}

QByteArray myfilewg::setGetCountJson(QString user, QString token)
{
    /*
     {
        user: xxx
        token: xxx
     }
    */
    QJsonObject obj;
    obj.insert("user", user);
    obj.insert("token", token);

    QJsonDocument doc(obj);
    if(doc.isNull() || doc.isEmpty())
    {
        cout << "doc.isNULL || doc.isEmpty";
        return 0;
    }

    return doc.toJson();
}

QStringList myfilewg::getCountStatus(QByteArray json)
{
    /*
    {
        code: xxx
        num: xxx
    }
     */
    QJsonParseError error;
    QStringList list;

    QJsonDocument doc = QJsonDocument::fromJson(json, &error);
    if(error.error == QJsonParseError::NoError)
    {
        if(doc.isNull() || doc.isEmpty())
        {
            cout << "doc.isNull() || doc.isEmpty()";
            return list;
        }

        if(doc.isObject())
        {
            QJsonObject obj = doc.object();
            list.append(obj.value("code").toString());
            list.append(obj.value("num").toString());
        }
    }
    else
    {
        cout << "err = " << error.errorString();
    }

    return list;
}

void myfilewg::clearFileList()
{
    int n = m_fileList.size();
    for(int i = 0; i < n; i++)
    {
        FileInfo* tmp = m_fileList.takeFirst();
        delete tmp;
    }
}

void myfilewg::getUserFilesList(Display cmd)
{
    if(m_userFilesCount <= 0)
    {
        cout << "获取用户文件列表条件结束";
        refreshFileItems();
        return;
    }
    else if(m_count > m_userFilesCount)
    {
        m_count = m_userFilesCount;
    }

    QNetworkRequest request;

    LoginInfoInstance* login = LoginInfoInstance::getInstance();

    QString url;
    QString tmp;
    if(cmd == Normal)
    {
        tmp = "normal";
    }
    else if(cmd == PvAsc)
    {
        tmp = "pvasc";
    }
    else if(cmd == PvDesc)
    {
        tmp = "pvdesc";
    }

    url = QString("http://%1:%2/myfiles?cmd=%3").arg(login->getIp()).arg(login->getPort()).arg(tmp);
    cout << "url: " << url;
    request.setUrl(QUrl(url));
    //qt默认请求头
    //request.setRawHeader("Content-Type", "text/html");
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    /*
     * 发送的json
     {
        "user": "milo",
        "token": "xxx",
        "start": 0,
        "count": 10
     }
    */
    QByteArray data = setFilesListJson(login->getUser(), login->getToken(), m_start, m_count);

    m_start += m_count;
    m_userFilesCount -= m_count;

    QNetworkReply* reply = m_manager->post(request, data);
    cout << "data: " << data;
    if(reply == nullptr)
    {
        cout << "reply == nullptr";
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            return;
        }

        QByteArray array = reply->readAll();
//        cout << "=====================";
//            qDebug() << array.length() << "\t" << array.data();
//        cout << "=====================";

        reply->deleteLater();

        if("111" == m_cm.getCode(array))
        {
            QMessageBox::warning(this, "账户异常", "请重新登陆！！！");
            emit loginAgainSignal(); //发送重新登陆信号

            return; //中断
        }

        if("015" != m_cm.getCode(array))
        {
            getFileJsonInfo(array);//解析文件列表json信息，存放在文件列表中

            //继续获取用户文件列表
            getUserFilesList(cmd);
        }
    });
}

void myfilewg::getFileJsonInfo(QByteArray data)
{
    /*
    {
    "user": "milo",
    "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
    "create_time": "2020-06-21 21:35:25",
    "file_name": "test.mp4",
    "share_status": 0,
    "pv": 0,
    "url": "http://192.168.52.139:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
    "size": 27473666,
     "type": "mp4"
    }
    */

    //-- user	文件所属用户
    //-- md5 文件md5
    //-- create_time 文件创建时间
    //-- file_name 文件名字
    //-- shared_status 共享状态, 0为没有共享， 1为共享
    //-- pv 文件下载量，默认值为0，下载一次加1
    //-- url 文件url
    //-- size 文件大小, 以字节为单位
    //-- type 文件类型： png, zip, mp4……

    QJsonParseError error;

    QJsonDocument doc = QJsonDocument::fromJson(data, &error);
    if(error.error == QJsonParseError::NoError)
    {
        if(doc.isNull() || doc.isEmpty())
        {
            cout << "doc.isNULL() || doc.isEmpty()";
            return;
        }

        if(doc.isObject())
        {
            QJsonObject obj = doc.object();
            QJsonArray array = obj.value("files").toArray();

            int size = array.size();
            cout << "size = " << size;

            for(int i = 0; i < size; ++i)
            {
                QJsonObject tmp = array[i].toObject();

                FileInfo* info = new FileInfo;
                info->user = tmp.value("user").toString();
                info->md5 = tmp.value("md5").toString();
                info->createTime = tmp.value("create_time").toString();
                info->filename = tmp.value("file_name").toString();
                info->shareStatus = tmp.value("share_status").toInt();
                info->pv = tmp.value("pv").toInt();
                info->url = tmp.value("url").toString();
                info->size = tmp.value("size").toInt();
                info->type = tmp.value("type").toString();
                QString type = info->type + ".png";
                info->icon = QIcon(m_cm.getFileType(type));
                info->item = new QListWidgetItem(info->icon, info->filename);
                m_fileList.append(info);
            }
        }
    }
    else
    {
        cout << "error = " << error.errorString();
    }
}

void myfilewg::clearItems()
{
    int n = ui->listWidget->count();
    for(int i = 0; i < n; ++i)
    {
        QListWidgetItem* item = ui->listWidget->takeItem(0);
        delete item;
    }
}

void myfilewg::addUploadItem(QString iconPath, QString name)
{
    ui->listWidget->addItem(new QListWidgetItem(QIcon(iconPath), name));
}

void myfilewg::uploadFilesAction()
{
    UploadTask* uploadList = UploadTask::getInstance();
    if(uploadList == nullptr)
    {
        cout << "UploadTask::getInstance() == nullptr";
        return;
    }

    if(uploadList->isEmpty())
    {
        return;
    }

    if(uploadList->isUpload())
    {
        return;
    }

    LoginInfoInstance* login = LoginInfoInstance::getInstance();

    QNetworkRequest request;
    QString url = QString("http://%1:%2/md5").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    UploadFileInfo* info = uploadList->takeTask();

    QByteArray array = setMd5Json(login->getUser(), login->getToken(), info->md5, info->fileName);

    QNetworkReply* reply = m_manager->post(request, array);
    if(reply == nullptr)
    {
        cout << reply->errorString();
        reply->deleteLater();
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            return;
        }

        QByteArray array = reply->readAll();
        cout << "md5_url: " << array << endl;
        reply->deleteLater();

        /*
        秒传文件：
            文件已存在：{"code":"005"}
            秒传成功：  {"code":"006"}
            秒传失败：  {"code":"007"}
            token验证失败：{"code":"111"}

        */
        QString code = m_cm.getCode(array);
        if("006" == code)
        {
            refreshFiles();
            m_cm.writeRecord(login->getUser(), info->fileName, code);
            QMessageBox::information(this, tr("成功"), tr("文件保存成功！"));
            uploadList->dealUploadTask();
        }
        else if("007" == code)
        {
            uploadFile(info);
        }
        else if("005" == code)
        {
            m_cm.writeRecord(login->getUser(), info->fileName, code);
            QMessageBox::warning(this, "文件存在", "该文件已存在！！！");
            uploadList->dealUploadTask();
        }
        else if("111" == m_cm.getCode(array)) //token验证失败
        {
            QMessageBox::warning(this, "账户异常", "请重新登陆！！！");
            emit loginAgainSignal(); //发送重新登陆信号
            return;
        }
    });
}

void myfilewg::downloadFilesAction()
{
    DownloadTask* p = DownloadTask::getInstance();
    if(p == nullptr)
    {
        cout << "DownloadTask::getInstance() == nullptr";
        return;
    }

    if(p->isEmpty())
    {
        return;
    }

    if(p->isDownload())
    {
        return;
    }

    if(p->isShareTask() == true)
    {
        return;
    }

    DownloadInfo* info = p->takeTask();

    QUrl url = info->url;
    QFile* file = info->file;
    QString md5 = info->md5;
    QString user = info->user;
    QString filename = info->filename;
    DataProgress* dp = info->dp;

    QNetworkReply* reply = m_manager->get(QNetworkRequest(url));
    if(reply == nullptr)
    {
        p->dealDownloadTask();
        cout << "get error";
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        cout << "下载完成";
        reply->deleteLater();
        p->dealDownloadTask();

        m_cm.writeRecord(user, filename, "010");

        dealFilePv(md5, filename);
    });

    connect(reply, &QNetworkReply::readyRead, [=]()
    {
        if(file != nullptr)
        {
            QByteArray data = reply->readAll();
            cout << data << endl;
            file->write(data);
        }
    });

    connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesRead, qint64 totalBytes)
    {
        dp->setProgress(bytesRead/1024, totalBytes/1024);
    });
}

void myfilewg::dealSelectdFile(QString cmd)
{
    QListWidgetItem* item = ui->listWidget->currentItem();
    if(item == nullptr)
    {
        return;
    }

    for(int i = 0; i < m_fileList.size(); ++i)
    {
        if(m_fileList.at(i)->item == item)
        {
            if(cmd == "分享")
            {
                shareFile(m_fileList.at(i));
            }
            else if(cmd == "删除")
            {
                delFile(m_fileList.at(i));
            }
            else if(cmd == "属性")
            {
                getFileProperty(m_fileList.at(i));
            }
            break;
        }
    }
}

void myfilewg::shareFile(FileInfo *info)
{
    if(info->shareStatus == 1)
    {
        QMessageBox::warning(this, "此文件已经分享", "此文件已经分享！！！");
        return;
    }

    QNetworkRequest request;

    LoginInfoInstance* login = LoginInfoInstance::getInstance();

    QString url = QString("http://%1:%2/dealfile?cmd=share").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    /*
    {
        "user": "milo",
        "token": "xxxx",
        "md5": "xxx",
        "filename": "xxx"
    }
    */

    QByteArray data = setDealFileJson(login->getUser(), login->getToken(), info->md5, info->filename);

    QNetworkReply* reply = m_manager->post(request, data);
    if(reply == nullptr)
    {
        cout << "reply == nullptr";
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            return;
        }

        QByteArray array = reply->readAll();
        reply->deleteLater();
        /*
        分享文件：
            成功：{"code":"010"}
            失败：{"code":"011"}
            别人已经分享此文件：{"code", "012"}

        token验证失败：{"code":"111"}

        */
        QString code = m_cm.getCode(array);
        if("010" == code)
        {
            info->shareStatus = 1;
            QMessageBox::information(this, "分享成功", QString("[%1] 分享成功！！！").arg(info->filename));
        }
        else if("011" == code)
        {
            QMessageBox::warning(this, "分享失败", QString("[%1] 分享失败！！！").arg(info->filename));
        }
        else if("111" == code)
        {
            QMessageBox::warning(this, "账户异常", "请重新登录！！！");
            emit loginAgainSignal();
            return;
        }
    });
}

void myfilewg::delFile(FileInfo *info)
{
    QNetworkRequest request;

    LoginInfoInstance* login = LoginInfoInstance::getInstance();

    QString url = QString("http://%1:%2/dealfile?cmd=del").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    /*
    {
        "user": "milo",
        "token": "xxxx",
        "md5": "xxx",
        "filename": "xxx"
    }
    */

    QByteArray data = setDealFileJson(login->getUser(), login->getToken(), info->md5, info->filename);

    QNetworkReply* reply = m_manager->post(request, data);
    if(reply == nullptr)
    {
        cout << "reply == nullptr";
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            return;
        }

        QByteArray array = reply->readAll();
        reply->deleteLater();
        /*
        删除文件：
            成功：{"code":"013"}
            失败：{"code":"014"}
        */

        if("013" == m_cm.getCode(array))
        {
            QMessageBox::information(this, "文件删除成功", QString("[%1] 删除成功！！！").arg(info->filename));
            for(int i = 0; i < m_fileList.size(); ++i)
            {
                if(m_fileList.at(i) == info)
                {
                    QListWidgetItem* item = info->item;
                    ui->listWidget->removeItemWidget(item);
                    delete item;

                    m_fileList.removeAt(i);
                    delete info;
                    break;
                }
            }
        }
        else if("014" == m_cm.getCode(array))
        {
            QMessageBox::information(this, "文件删除失败", QString("[%1] 删除失败！！！").arg(info->filename));
        }
        else if("111" == m_cm.getCode(array))
        {
            QMessageBox::warning(this, "账户异常", "请重新登陆！！！");
            emit loginAgainSignal(); //发送重新登陆信号

            return; //中断
        }
    });
}

void myfilewg::getFileProperty(FileInfo *info)
{
    FilePropertyInfo dlg;//创建对话框
    dlg.setWindowTitle(info->filename);
    dlg.setWindowIcon(info->icon);
    dlg.setInfo(info);
    dlg.exec();//模态方式运行
}

QByteArray myfilewg::setMd5Json(QString user, QString token, QString md5, QString fileName)
{
    QMap<QString, QVariant> tmp;
    tmp.insert("user", user);
    tmp.insert("token", token);
    tmp.insert("md5", md5);
    tmp.insert("fileName", fileName);

    /*json数据如下
    {
        user:xxxx,
        token:xxxx,
        md5:xxx,
        fileName: xxx
    }
    */
    QJsonDocument doc = QJsonDocument::fromVariant(tmp);
    if(doc.isNull())
    {
        cout << "jsonDocument.isNull()";
        return "";
    }

    return doc.toJson();
}

void myfilewg::uploadFile(UploadFileInfo *info)
{
    cout << "真正上传文件" << endl;

    QFile* file = info->file;
    QString fileName = info->fileName;
    QString md5 = info->md5;
    qint64 size = info->size;
    DataProgress* dp = info->dp;
    QString boundary = m_cm.getBoundary();

    LoginInfoInstance* login = LoginInfoInstance::getInstance();

    /*
    QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart filePart;
//    QFileInfo fileInfo(fileName);
//    QString contentType = QMimeDatabase().mimeTypeForFile(fileInfo).name();
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data; user=\"%1\"; filename=\"%2\"; md5=\"%3\"; size=\"%4\"").arg(login->getUser()).arg(fileName).arg(md5).arg(size)));
    filePart.setBodyDevice(file);
    multiPart->append(filePart);

    QNetworkRequest request;
    QString url = QString("http://%1:%2/upload").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));

//    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkReply* reply = m_manager->post(request, multiPart);

    if(reply == nullptr)
    {
        cout << "reply == nullptr";
        delete multiPart;
        return;
    }
    multiPart->setParent(reply);

    */
#if 1
    QByteArray data;

    data.append(boundary);
    data.append("\r\n");
    data.append("Content-Disposition: form-data; ");
    data.append(QString("user=\"%1\" ").arg(login->getUser()));
    data.append(QString("filename=\"%1\" ").arg(fileName));
    data.append(QString("md5=\"%1\" ").arg(md5));
    data.append(QString("size=%1").arg(size));
    data.append("\r\n");

    data.append(QString("Content-Type: application/octet-stream"));
    data.append("\r\n");
    data.append("\r\n");

    data.append(file->readAll());
    data.append("\r\n");
    data.append(QString("%1--").arg(boundary));


    QNetworkRequest request;
    QString url = QString("http://%1:%2/upload").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/octet-stream; boundary=%1").arg(boundary));
//    request.setRawHeader("Transfer-Encoding", "chunked");

    QNetworkReply* reply = m_manager->post(request, data);
    if(reply == NULL)
    {
        cout << "reply == NULL";
        return;
    }

    connect(reply, &QNetworkReply::uploadProgress, [=](qint64 bytesRead, qint64 totalBytes)
    {
        if(totalBytes != 0)
        {
            dp->setProgress(bytesRead/1024, totalBytes/1024);
        }
    });

    connect(reply, &QNetworkReply::finished, [=]()
    {
        UploadTask* uploadList = UploadTask::getInstance();
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            uploadList->dealUploadTask();
            return;
        }

        QByteArray array = reply->readAll();
        reply->deleteLater();

        /*
       上传文件：
           成功：{"code":"008"}
           失败：{"code":"009"}
       */

        cout << array << endl;
        QString code = m_cm.getCode(array);
        if("008" == code)
        {
            m_cm.writeRecord(login->getUser(), info->fileName, code);
        }
        else if("009" == code)
        {
            m_cm.writeRecord(login->getUser(), info->fileName, code);
        }

        if(uploadList == nullptr)
        {
            cout << "UploadTask::getInstance() == nullptr";
            return;
        }
        refreshFiles();
        uploadList->dealUploadTask();
    });

#else
    QNetworkRequest request;
    QString url = QString("http://%1:%2/upload").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream; charset=utf-8");
//    request.setRawHeader("Transfer-Encoding", "chunked"); // 设置Transfer-Encoding为chunked

    QNetworkReply* reply = nullptr;

    QByteArray data;

    qint64 blockSize = 2 * 1024;
    qint64 fileSize = file->size();

    qint64 currentPos = 0;

    while(currentPos < fileSize)
    {
        if(file->seek(currentPos))
        {
            QByteArray array = file->read(blockSize);
            data.append(array);
            currentPos += array.size();
cout << data << endl;
            request.setHeader(QNetworkRequest::ContentLengthHeader, blockSize);
            reply = m_manager->post(request, data);
            if(reply == NULL)
            {
                cout << "reply == NULL";
                return;
            }

            connect(reply, &QNetworkReply::finished, [=]()
            {
                UploadTask* uploadList = UploadTask::getInstance();
                if(reply->error() != QNetworkReply::NoError)
                {
                    cout << reply->errorString();
                    reply->deleteLater();
                    uploadList->dealUploadTask();
                    return;
                }

                QByteArray array = reply->readAll();
                reply->deleteLater();
                cout << array << endl;
            });

            data.clear();
        }
        else
        {
            break;
        }
    }

#endif
}

void myfilewg::addDownloadFiles()
{
    emit gotoTransfer(TransferStatus::Download);
    QListWidgetItem* item = ui->listWidget->currentItem();
    if(item == nullptr)
    {
        cout << "item == nullptr";
        return;
    }

    DownloadTask* p = DownloadTask::getInstance();
    if(p == nullptr)
    {
        cout << "DownloadTask::getInstance() error";
        return;
    }

    for(int i = 0; i < m_fileList.size(); ++i)
    {
        if(m_fileList.at(i)->item == item)
        {
            QString filePathName = QFileDialog::getSaveFileName(this, "选择保存文件路径", m_fileList.at(i)->filename);
            if(filePathName.isEmpty())
            {
                cout << "filePathName.isEmpty() error";
                return;
            }
            /*
               下载文件：
                    成功：{"code":"009"}
                    失败：{"code":"010"}
            */
            //cout << filePathName;

            //追加任务到下载队列
            //参数：info：下载文件信息， filePathName：文件保存路径
            //成功：0
            //失败：
            //  -1: 下载的文件是否已经在下载队列中
            //  -2: 打开文件失败
            int res = p->appendDownloadList(m_fileList.at(i), filePathName);
            if(res == -1)
            {
                QMessageBox::warning(this, "任务已存在", "任务已经在下载队列中！！！");
            }
            else if(res == -2)
            {
                m_cm.writeRecord(m_fileList.at(i)->user, m_fileList.at(i)->filename, "101");
            }

            break;
        }
    }
}

void myfilewg::dealFilePv(QString md5, QString fileName)
{
    QNetworkRequest request;

    LoginInfoInstance* login = LoginInfoInstance::getInstance();

    QString url = QString("http://%1:%2/dealfile?cmd=pv").arg(login->getIp()).arg(login->getPort());
    request.setUrl(QUrl(url));

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    /*
    {
        "user": "milo",
        "token": "xxx",
        "md5": "xxx",
        "filename": "xxx"
    }
    */
    QByteArray data = setDealFileJson(login->getUser(), login->getToken(), md5, fileName);

    QNetworkReply* reply = m_manager->post(request, data);
    if(reply == nullptr)
    {
        cout << "reply == nullptr";
        return;
    }

    connect(reply, &QNetworkReply::finished, [=]()
    {
        if(reply->error() != QNetworkReply::NoError)
        {
            cout << reply->errorString();
            reply->deleteLater();
            return;
        }

        QByteArray array = reply->readAll();

        reply->deleteLater();
        /*
        下载文件pv字段处理
            成功：{"code":"016"}
            失败：{"code":"017"}
        */
        QString code = m_cm.getCode(array);
        if("016" == code)
        {
            for(int i = 0; i < m_fileList.size(); ++i)
            {
                FileInfo* info = m_fileList.at(i);
                if(info->md5 == md5 && info->filename == fileName)
                {
                    int pv = info->pv;
                    info->pv = pv+1;
                    break;
                }
            }
        }
        else
        {
            cout << "下载文件pv字段处理失败";
        }
    });
}

void myfilewg::refreshFileItems()
{
    clearItems();

    if(m_fileList.isEmpty() == false)
    {
        int n = m_fileList.size();
        for(int i = 0; i < n; ++i)
        {
            FileInfo* tmp = m_fileList.at(i);
            QListWidgetItem* item = tmp->item;
            ui->listWidget->addItem(item);
        }
    }

    this->addUploadItem();
}

QByteArray myfilewg::setFilesListJson(QString user, QString token, int start, int count)
{
    /*
     * 发送的json
     {
        "user": "milo",
        "token": "xxx",
        "start": 0,
        "count": 10
     }
    */
    QMap<QString, QVariant> obj;
    obj.insert("user", user);
    obj.insert("token", token);
    obj.insert("start", start);
    obj.insert("count", count);

    QJsonDocument doc = QJsonDocument::fromVariant(obj);
    if(doc.isNull() || doc.isEmpty())
    {
        cout << "doc.isNULL || doc.isEmpty";
        return 0;
    }

    return doc.toJson();
}

QByteArray myfilewg::setDealFileJson(QString user, QString token, QString md5, QString filename)
{
    /*
    {
        "user": "milo",
        "token": "xxxx",
        "md5": "xxx",
        "filename": "xxx"
    }
    */

    QMap<QString, QVariant> tmp;
    tmp.insert("user", user);
    tmp.insert("token", token);
    tmp.insert("md5", md5);
    tmp.insert("filename", filename);

    QJsonDocument doc = QJsonDocument::fromVariant(tmp);
    if(doc.isEmpty() || doc.isNull())
    {
        cout << "doc.isNULL || doc.isEmpty";
        return 0;
    }

    return doc.toJson();
}
